﻿//--------------------------------------------------------------------------------------------------------------------------------------------------------
// <copyright file="ControllerExtensions.cs">
//     Copyright © 2010 Oli Francis
//     This source code is subject to the terms and conditions of the MIT license. A copy of the license can be found in the license.txt 
//     file at the root of this distribution. By using this source code in any fashion, you are agreeing to be bound by the terms of the MIT License. 
//     You must not remove this notice from the software.
// </copyright>
// <author>Oli</author>
//-------------------------------------------------------------------------------------------------------------------------------------------------------

namespace TeamBrain.Web.Utilities
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;

    /// <summary>
    /// Extension methods for Controller class
    /// </summary>
    public static class ControllerExtensions
    {
        /// <summary>
        /// Calls a particular action method but first applies model validation to the given type
        /// </summary>
        public static ActionResult CallWithModelValidation<TController, TResult, TModel>(
            this TController controller, Func<TController, TResult> action, TModel model)
            where TController : Controller
            where TResult : ActionResult
            where TModel : class
        {
            var provider = new DataAnnotationsModelValidatorProvider();
            var metadata = ModelMetadataProviders.Current.GetMetadataForProperties(model, typeof(TModel));

            foreach (var modelMetadata in metadata)
            {
                var validators = provider.GetValidators(modelMetadata, new ControllerContext());

                foreach (var validator in validators)
                {
                    var results = validator.Validate(model);

                    foreach (var result in results)
                    {
                        controller.ModelState.AddModelError(modelMetadata.PropertyName, result.Message);
                    }
                }
            }

            return action(controller);
        }
    }
}